﻿namespace WebPacker.Tests.Packs.Resources
{
	using System;
	using System.IO;
	using System.Linq;
	using System.Text;
	using NUnit.Framework;
	using WebPacker.Packs.Resources;

	[TestFixture]
	public class WildcardFileResourceTest
	{
		private readonly string testPath;
		private readonly string[] testFiles;

		public WildcardFileResourceTest()
		{
			testPath = TestHelper.GetSampleFolder("wildcard");
			testFiles = TestHelper.PrepareSampleFiles(new string[] { "test1.js", "test2.js", "style1.css" }, "wildcard");
		}

		[Test]
		public void ConstructorNullTest()
		{
			Assert.Throws<ArgumentNullException>(() => new WildcardFileResource(null));
		}

		[Test]
		public void ConstructorError1Test()
		{
			Assert.Throws<ArgumentException>(() => new WildcardFileResource(@"c:\test\"));
		}

		[Test]
		public void ConstructorError2Test()
		{
			Assert.Throws<ArgumentException>(() => new WildcardFileResource(@"c:\test\te|<>.dwe"));
		}

		[Test]
		public void ConstructorMaskTest()
		{
			var name = "c:/test/*.js";
			var resource = new WildcardFileResource(name);
			Assert.AreEqual(name.Replace("/", "\\"), resource.Name);
			Assert.AreEqual("c:\\test", resource.SearchPath);
			Assert.AreEqual("*.js", resource.SearchPattern);
			Assert.AreEqual(Encoding.UTF8, resource.Encoding);
		}

		[Test]
		public void ConstructorMask2Test()
		{
			var name = @"c:\test2\s*.c??";
			var resource = new WildcardFileResource(name);
			Assert.AreEqual("c:\\test2", resource.SearchPath);
			Assert.AreEqual("s*.c??", resource.SearchPattern);
			Assert.AreEqual(Encoding.UTF8, resource.Encoding);
		}

		[Test]
		public void ConstructorMask3Test()
		{
			var name = @"*.css";
			var resource = new WildcardFileResource(name);
			Assert.IsEmpty(resource.SearchPath);
			Assert.AreEqual("*.css", resource.SearchPattern);
			Assert.AreEqual(Encoding.UTF8, resource.Encoding);
		}

		[Test]
		public void GetFileNamesTest()
		{
			var resource = new WildcardFileResource(testPath + "/*.*");
			Assert.That(resource.GetFileNames(), Is.Ordered);
		}

		[Test]
		public void GetContentTest()
		{
			var resource = new WildcardFileResource(testPath + "/*.*");
			var actual = resource.GetContent();
			Assert.IsNotNull(actual);
			var expected = string.Join(string.Empty, testFiles.OrderBy(x => x).Select(x => File.ReadAllText(x)));
			Assert.AreEqual(expected, actual);
		}

		[Test]
		public void GetLastModifiedTest()
		{
			var resource = new WildcardFileResource(testPath + "/*.*");
			var expected = testFiles.Select(x => File.GetLastWriteTime(x)).Max();
			Assert.AreEqual(expected, resource.GetLastModifiedTime());
		}

		[Test]
		public void GetResourcesTest()
		{
			var resource = new WildcardFileResource(testPath + "/*.js");
			var expected = testFiles.Where(x => x.EndsWith(".js")).ToArray();
			var actual = resource.GetResources().ToArray();
			Assert.IsNotNull(actual);
			Assert.AreEqual(expected.Length, actual.Length);
			Assert.That(actual.Select(x => x.Name), Is.EquivalentTo(expected));
		}
	}
}
